Today, compilers, for example, Binary Translation (BT) compilers and Just-In-Time (JIT) converters may generate output code for execution on a machine or processor. Ordinarily, compilers or convertors take source code and create executable BT or JIT output. Compilers may statically compile source code into machine code for execution on the same machine or processor or may create byte code on a first machine or processor, wherein the bytecode is subsequently input to a JIT compiler, a dynamic compiler, on a second machine or processor. Compilers perform this conversion and may generate memory-maps for identifying instructions and identifying data. Further, these memory maps may identify modifiable and non-modifiable memory locations for code and data. Similarly, JIT conversion may convert pseudo code (e.g., interpreted code) and convert it into native code during execution. During BT or JIT conversion, dynamic output code that is generated is intended to be only executed and not modified. However, unless protected, output code may become a target of an attack such as, for example, attack by malware or similar that exploits vulnerabilities in the generated output code.
Current protection methods for BT or JIT compilation include writing BT/JIT code into memory pages and declaring these memory pages as read-only (or execute only). Another protection method segments output code and injects guard pages between these segments. However, these methods are not effective. Memory paging and segmentation require expensive hypervisor or operating system (OS) operations to mark memory pages as read-only in page tables and/or in extended page tables, and for very dynamic type of code translation, the overhead of a hypervisor or OS can be very high. Additionally, paging mechanisms define large blocks of memory for pages (typically 4096 bytes) as read-only for enforcement of security access rights. However, if certain memory regions in these memory pages need to be changed later (for example, to optimize performance), it is impossible to change these memory pages without changing how the BT or JIT output code is generated. A technique for protecting compiler output code and data generated dynamically with finer grain granularity would be desirable.